use std::sync::Arc;
use std::env;
use dotenv::dotenv;
use axum::{response::IntoResponse, routing::get, Router, Json};
use sea_orm::{Database, ConnectOptions};

mod state;

async fn health_checker_handler() -> impl IntoResponse {
    const MESSAGE: &str = "Simple CURD API";

    let json_response = serde_json::json!({
        "status": "success",
        "message": MESSAGE
    });

    Json(json_response)
}

#[tokio::main]
async fn main() {
    dotenv().ok();
    
    // Setup database connection
    let max_connections = env::var("MAX_CONNECTIONS").unwrap_or_else(|_| "100".to_string()).parse::<u32>().unwrap();
    let min_connections = env::var("MIN_CONNECTIONS").unwrap_or_else(|_| "5".to_string()).parse::<u32>().unwrap();
    let mut opt = ConnectOptions::new(env::var("DATABASE_URL").unwrap());
    opt.max_connections(max_connections)
        .min_connections(min_connections);

    // Setup application state
    let db = Database::connect(opt).await.unwrap();
    let app_state = Arc::new(state::AppState{db: db});
    

    // Start server
    let app = Router::new().route("/api/healthchecker", get(health_checker_handler)).with_state(app_state);
    let host = env::var("HOST").unwrap_or_else(|_| "127.0.0.1".to_string());
    let port = env::var("PORT").unwrap_or_else(|_| "3200".to_string());
    let listener = tokio::net::TcpListener::bind(format!("{}:{}", host, port)).await.unwrap();
    println!("Server started successfully");
    axum::serve(listener, app).await.unwrap();
}
